home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 076-100 / disk_086 / clicktofront / clicktofront.asm < prev    next >
Assembly Source File  |  1992-05-06  |  13KB  |  476 lines

  1. ;ClickToFront V1.1 Copyright 1987 Bryce Nesbitt.  Unlimited, revokable, free,
  2. ;non-exclusive licence hereby granted to any sentient being to use or abuse
  3. ;this code in any way whatsoever provided that this and any other copyright
  4. ;notices remain fully attached and are reproduced in any simultaneously
  5. ;distributed printed matter and with the exception that, without prior
  6. ;written permission, it not be utilized by any entity that has been commonly
  7. ;referred to as Robert W. Skyles, Skyles Electric Works, Jim Drew, Regie
  8. ;Warren or any organization founded by, controlled, employing or profiting
  9. ;any such entity, it's offspring or spouses.  FISH use ok.  Author
  10. ;correspondence, bug or stupidity reports may be directed to:
  11. ;    1712 Marin Ave.
  12. ;    Berkeley, Ca 94707-2902
  13. ;    bryce@cogsci.berkeley.EDU -or- ucbvax!cogsci!bryce
  14. ;"(almost) as seen in Transactor magazine".
  15. ;
  16. ;USAGE
  17. ;    CLI - ClickToFront
  18. ;    WB  - Brings up requester, choose Install or Cancel
  19. ;
  20. ;    A click into any part of any window works as normal.
  21. ;    A double click brings it to the front.    How handy!
  22. ;
  23. ;    !!! In order to prevent false activation, lower the !!!
  24. ;    !!! double-click sensitvity from preferences.        !!!
  25. ;
  26. ;BUGS
  27. ;   No provisions for un-install.  The only way I can think to do this would
  28. ;be to add a handler at priority 52, then search the chain downward for a
  29. ;handler with name ClickToFront.  This seems like a kludge.
  30. ;   This program is NOT Intuition.  This makes certain things more difficult.
  31. ;A test should be made that both clicks are over the same window.  If some,
  32. ;kind Intuition() hacker has a way...
  33. ;   No longer brings screens to the front.
  34. ;   Proper size when assembled with Metacomco and Blink'ed with NODEBUG
  35. ;   is 956 bytes.
  36. ;
  37. **************
  38.     NOLIST
  39.     INCLUDE 'exec/types.i'
  40.     INCLUDE 'exec/memory.i'
  41.     INCLUDE 'exec/interrupts.i'
  42.     INCLUDE 'exec/io.i'
  43. ;    INCLUDE 'exec/tasks.i'
  44. ThisTask    EQU $114
  45.     INCLUDE 'libraries/dosextens.i'
  46.     INCLUDE 'devices/inputevent.i'
  47.     INCLUDE 'devices/input.i'
  48. ;    INCLUDE 'intuition/intuitionbase.i'
  49. ib_ActiveWindow EQU $34
  50. ib_ActiveScreen EQU $38
  51. ib_FirstScreen    EQU $3C
  52. ;
  53. ;What follows is a non-standard extension that eliminates the need to link
  54. ;with the HUGE amiga.lib file.
  55. ;
  56.     ;INCLUDE 'lib/exec_lib.i'
  57.     ;INCLUDE 'lib/intuition_lib.i'
  58.     LIST
  59. jsrlib    macro
  60.  xref _LVO\1
  61.  jsr  _LVO\1(a6)
  62.  endm
  63. jmplib    macro
  64.  xref _LVO\1
  65.  jmp  _LVO\1(a6)
  66.  endm
  67. ********************
  68.         CODE
  69. startup:    move.l    4,a6
  70.         move.l    ThisTask(a6),a5
  71.         moveq    #0,d0        ;Set zero for later
  72.         move.l    pr_CLI(a5),d1    ;Pointer to CLI only structure
  73.         bne.s    fromCLI     ;If not zero, then save a zero...
  74. ;
  75. ; If called from Workbench a message will be sent.  This waits for it,
  76. ;  and saves it's pointer to be returned to Workbench later.
  77. ;
  78.         lea.l    pr_MsgPort(a5),a0
  79.         jsrlib    WaitPort
  80.         lea.l    pr_MsgPort(a5),a0
  81.         jsrlib    GetMsg        ;Message pointer in D0
  82. fromCLI     move.l    d0,-(a7)    ;Save message for later...
  83. ******************************** [A6=ExecBase][a5=this task]
  84. failcode    equr    d7
  85. Ibase        equr    d6
  86. portsave    equr    a5
  87. IOReqsave    equr    a4
  88.  
  89.         moveq    #20,failcode    ;Default code
  90. ;---Prepare StdIO---
  91.         bsr    _CreatePortE    ;[d0=Port]
  92.         beq    ExitToDOS
  93.         move.l    d0,portsave
  94.         bsr    _CreateStdIOE    ;[a1=IoRequest]
  95.         beq    e_StdIO
  96.         move.l    a1,IOReqsave
  97. ;---Open input.device---
  98.         moveq    #0,d0        ;Unit
  99.         move.l    d0,d1        ;Flags
  100.         lea.l    devname(pc),a0
  101.         ;[a1-IoRequest]
  102.         jsrlib    OpenDevice    ;[d0=zero if ok]
  103.         tst.l    d0
  104.         bne    e_Open
  105. ;---Open Intuition---
  106. ;Intuition will be opened, and the pointer given to the interrupt code
  107. ; Since the interrupt will still be installed after this task exits,
  108. ; intuition will be left open.
  109. ;
  110.         lea.l    IntuiName(pc),a1
  111.         jsrlib    OldOpenLibrary    ;V1.0 Compatible :-)
  112.         move.l    d0,Ibase    ;(d)
  113.         beq    e_Intui
  114.         tst.l    (a7)        ;check CLI flag on stack
  115.         beq.s    DoIt        ;always do it from CLI
  116.  
  117.         move.l    Ibase,a6
  118.         suba.l    a0,a0
  119.         lea.l    IText1(pc),a1
  120.         lea.l    IText2(pc),a2
  121.         lea.l    IText3(pc),a3
  122.         moveq    #0,d0
  123.         moveq    #0,d1
  124.         move.l    #560,d2
  125.         moveq    #68,d3
  126.         jsrlib    AutoRequest
  127.         move.l    4,a6
  128.         tst.l    d0        ;grumble, gritch, grrr...
  129.         bne.s    DoIt
  130. ;---User said no, so pack our bags and go home--
  131.         move.l    Ibase,a1
  132.         jsrlib    CloseLibrary
  133.         bra.s    Cancel
  134. ;---Copy Handler---
  135. DoIt        move.l    #DownEnd-Start,d0
  136.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  137.         jsrlib    AllocMem
  138.         move.l    d0,a2        ;location of block
  139.         move.l    d0,a1
  140.         tst.l    d0
  141.         beq.s    e_nomem
  142.  
  143.         lea.l    Start(pc),a0
  144.         moveq    #((DownEnd-Start)/4)-1,d1 ;Length in LONGS-1
  145. copylp        move.l    (a0)+,(a1)+ ;Copy handler to Public Memory
  146.         dbra    d1,copylp   ;68010 Loop mode!
  147.  
  148. ;---Prepare IOReq with proper addresses---
  149.         lea.l    Handlercode-Start(a2),a0 ;offset+memblock
  150.         move.l    a0,IS_DATA(a2)         ;unused
  151.         move.l    a0,IS_CODE(a2)         ;where code is
  152.         lea.l    PopName-Start(a2),a0     ;set ascii name
  153.         move.l    a0,LN_NAME(a2)
  154.         move.l    Ibase,IBASE1+2-Start(a2) ;modify code
  155.         move.l    Ibase,IBASE2+2-Start(a2) ;modify code
  156.  
  157. ;---Send ADDHANDLER---
  158.         move.l    IOReqsave,a1
  159.         move.w    #IND_ADDHANDLER,IO_COMMAND(a1)
  160.         move.l    a2,IO_DATA(a1)
  161.         ;(IOReq in a1)
  162.         jsrlib    DoIO        ;d0=(IOReq-a0)
  163.         tst.l    d0
  164.         bne.s    e_DoIO    ;bad<>0.  Forget the memory...
  165.  
  166. Cancel        moveq    #0,d7
  167. e_nomem
  168. e_DoIO
  169. e_Intui     move.l    IOReqsave,a1
  170.         jsrlib    CloseDevice
  171. e_Open        move.l    IOReqsave,a1
  172.         bsr    _DeleteStdIOE
  173. e_StdIO     move.l    portsave,a1
  174.         bsr    _DeletePortE
  175.         tst.l    failcode
  176.         beq.s    ExitToDOS
  177.  
  178. ;-- There can be only one reason why we failed (knock on formica) --
  179. ;-- and that is lack of memory.  Unless you have a better idea... --
  180.  
  181.         move.l    ThisTask(a6),a1
  182.         moveq    #ERROR_NO_FREE_STORE,d0
  183.         move.l    d0,pr_Result2(a1)
  184.  
  185. ******************************* (a7)+=message d7=return code a6=exec
  186. ExitToDOS:    move.l    (a7)+,d2
  187.         beq.s    NotWB    ;If saved pointer is zero, exit to CLI...
  188. ;
  189. ; Return the startup message to the parent Workbench tool. The forbid
  190. ; is needed so workbench can't UnLoadSeg() the code too early.
  191. ;
  192.         jsrlib    Forbid
  193.         move.l    d2,a1        ;message pointer
  194.         jsrlib    ReplyMsg
  195. NotWB        move.l    failcode,d0    ;Set "failat" code
  196.         rts
  197.  
  198. ;**** exec_support/CreatePort ***
  199. ;
  200. ; port=_CreatePort()
  201. ;  d0
  202. ;
  203. ;FUNCTION:  Create a nameless message port with a 0 priority.
  204. ; (exec/ports.i)
  205. ;RESULT: The port pointer or Z=1 if an error occured.
  206. ;REGISTERS: a6 is destroyed unless _CreatePortE is called,
  207. ; in which case a6 must contain ExecBase.
  208. ;EXAMPLE:
  209. ;        moveq    #3,d0    ;Set Priority
  210. ;        jsr    _CreatePort
  211. ;        beq.s    noport    ;Not enough memory or signals
  212. ;
  213.         ;xref    _CreatePort
  214.         ;xref    _CreatePortE
  215. ;_CreatePort    move.l    4,a6
  216. _CreatePortE:    move.l    a2,-(a7)
  217.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  218.         moveq    #MP_SIZE,d0
  219.         jsrlib    AllocMem
  220.         move.l    d0,a2
  221.         tst.l    d0
  222.         beq.s    cp_nomemory
  223.         moveq    #-1,d0
  224.         jsrlib    AllocSignal    ;d0=return
  225.         moveq    #-1,d1
  226.         cmp.l    d0,d1    ;-1 indicates bad signal
  227.         bne.s    cp_sigok
  228.         move.l    a2,a1
  229.         moveq    #MP_SIZE,d0
  230.         jsrlib    FreeMem
  231. cp_nomemory    moveq    #0,d0    ;set z=1
  232.         bra.s    cp_xit
  233.  
  234. cp_sigok    move.b    d0,MP_SIGBIT(a2)
  235.         move.b    #PA_SIGNAL,MP_FLAGS(a2)
  236.         move.b    #NT_MSGPORT,LN_TYPE(a2)
  237.         clr.b    LN_PRI(a2)
  238.         move.l    ThisTask(a6),MP_SIGTASK(a2)
  239.         lea.l    MP_MSGLIST(a2),a0  ;Point to list header
  240.         NEWLIST a0        ;Init new list macro
  241.         move.l    a2,d0
  242. cp_xit        move.l    (a7)+,a2    ;cc's NOT affected
  243.         rts
  244.  
  245. ;**** exec_support/DeletePort ***
  246. ;
  247. ;_DeletePort(port)
  248. ;         a1
  249. ;
  250. ;FUNCTION:  Deletes the port by first setting some
  251. ; fields to illegal values then calling FreeMem.
  252. ;RESULT: none
  253. ;REGISTERS: a6 is destroyed unless _DeleteStdIOE is called,
  254. ; in which case a6 must contain ExecBase.
  255. ;
  256.         ;xref    _DeletePort
  257.         ;xref    _DeletePortE
  258. ;_DeletePort    move.l    4,a6
  259. _DeletePortE:    move.l    a1,-(a7)
  260.         moveq    #-1,d0
  261.         move.b    d0,LN_TYPE(a1)
  262.         move.l    d0,MP_MSGLIST+LH_HEAD(a1)
  263.         moveq    #0,d0    ;Clear upper 3/4 of d0
  264.         move.b    MP_SIGBIT(a1),d0
  265.         jsrlib    FreeSignal
  266.         move.l    (a7)+,a1
  267.         moveq    #MP_SIZE,d0
  268.         jmplib    FreeMem
  269. ;
  270. ;ioStdReq=CreateStdIO(ioReplyPort)
  271. ; a1            d0
  272. ;
  273. ;Function: Allocate a IoRequest block of standard size.
  274. ;Example:    move.l    MyPort,d0
  275. ;        jsr    _CreateStdIO
  276. ;        beq.s    badnews
  277. ;
  278.         ;xref    _CreateStdIOE
  279.         ;xref    _CreateStdIO
  280. ;_CreateStdIO    move.l    4,a6
  281. _CreateStdIOE:    move.l    d0,-(a7)
  282.         moveq    #IOSTD_SIZE,d0
  283.         move.l    #MEMF_PUBLIC+MEMF_CLEAR,d1
  284.         jsrlib    AllocMem
  285.         move.l    d0,a1
  286.         tst.l    d0
  287.         beq.s    nomem
  288.         move.b    #NT_MESSAGE,LN_TYPE(a1)
  289.         move.l    (a7)+,MN_REPLYPORT(a1)
  290. nomem        rts
  291.  
  292. ;*** exec_support/DeleteStdIO ***
  293. ;
  294. ;_DeleteStdIO(ioStdReq)
  295. ;        a1
  296. ;
  297. ;FUNCTION:  Deletes an ioStdReq by setting some
  298. ; fields to illegal values then calling FreeMem.
  299. ;RESULT: none
  300. ;REGISTERS: a6 is destroyed unless _DeleteStdIOE is called,
  301. ; in which case a6 must contain ExecBase.
  302. ;
  303.         ;xref    _DeleteStdIO
  304.         ;xref    _DeleteStdIOE
  305. ;_DeleteStdIO    move.l    4,a6    ;Get ExecBase
  306. _DeleteStdIOE:    moveq    #-1,d0    ;Set fields to illegal value
  307.         move.b    d0,LN_TYPE(a1)
  308.         move.l    d0,IO_DEVICE(a1)
  309.         move.l    d0,IO_UNIT(a1)
  310.         moveq    #IOSTD_SIZE,d0
  311.         jmplib    FreeMem
  312.  
  313. IText1: dc.b    0,1,1,0     ;pens, drawmode and filler
  314.     dc.w    20,6        ;XY
  315.     dc.l    0        ;NULL for default font
  316.     dc.l    ITextText1    ;pointer to text
  317.     dc.l    IText1b     ;next IntuitText structure
  318. IText1b dc.b    0,1,1,0
  319.     dc.w    20,17
  320.     dc.l    0
  321.     dc.l    ITextText1b
  322.     dc.l    0
  323.  
  324. IText2: dc.b    0,1,1,0
  325.     dc.w    6,3
  326.     dc.l    0
  327.     dc.l    ITextText2
  328.     dc.l    0
  329. IText3: dc.b    0,1,1,0
  330.     dc.w    6,3
  331.     dc.l    0
  332.     dc.l    ITextText3
  333.     dc.l    0
  334.  
  335. ITextText1:    dc.b 'ClickToFront installer v1.1.   '
  336.         dc.b $a9,'1987 Bryce Nesbitt',0
  337. ITextText1b    dc.b 'Double-clicking will bring '
  338. ITextText1c    dc.b 'any window to the front',0
  339. ITextText2:    dc.b 'Install',0
  340. ITextText3:    dc.b 'Cancel',0
  341. IntuiName:    dc.b 'intuition.library',0
  342. devname:    dc.b 'input.device',0
  343.  
  344. ;-------------------------------
  345.         cnop    0,4    ;LONG word align
  346. Start:
  347. ints:    ;This is an interrupt structure (exec/interrupts.i)
  348.     ;since it will be referenced by an interrupt it MUST be
  349.     ;copied into PUBLIC memory.  (All memory that will be used
  350.     ;by interrupts or other tasks must be PUBLIC.)
  351.     dc.l 0        ;succ
  352.     dc.l 0        ;pred
  353.     dc.b 0        ;type
  354.     dc.b 51     ;Priority (One step higher than Intuition)
  355.     dc.l 0        ;Name
  356.     dc.l 0        ;Data
  357.     dc.l 0        ;Code
  358. inte
  359.  
  360. ;When the handler is entered a0 will point to a linked list of input
  361. ; events of the type defined in the incude file (devices/inputevent.i)
  362. ; When done mangling the input stream it returns a new pointer in d0
  363. ;Note: All references to (a0) below refer to ie_NextEvent(a0).    The
  364. ; offeset equates to zero and was eliminated for effeciency.
  365.  
  366. Handlercode:    move.l    a0,d0        ;Save pointer to start of chain
  367.         cmpi.w    #$0200,ie_Class(a0)
  368.  
  369. ;Compare class AND subclass. $0200 is a combination of IECLASS_RAWMOUSE for
  370. ;ie_Class and IECLASS_NULL for ie_SubClass (it checks two BYTEs at once).
  371.  
  372.         beq.s    hurdle1
  373.         move.l    (a0),d1     ;Get {ie_NextEvent} pointer
  374.         bne.s    MoreEvents    ;If any...
  375.         rts            ;exit (with no changes made)
  376.  
  377. hurdle1     move.l    ie_Code(a0),d1    ;Code & Qualifier.
  378.         andi.w    #%0011000000000000,d1
  379. ;
  380. ;Mask off the bits of the qualifier field that we do not care about.  In this
  381. ; case that's all but the RIGHT and MIDDLE buttons, which may not be down.
  382.  
  383.         cmpi.l    #$00680000,d1
  384. ;
  385. ;The upper word of this comparison ($0068) is the RAWMOUSE code for LBUTTON
  386. ; the lower is the match for the qualifier.
  387.  
  388.         beq.s    CheckClick
  389. KeepLooking    move.l    (a0),d1     ;See above...
  390.         bne.s    MoreEvents    ;See above...
  391.         rts            ;exit (no changes)
  392. ;
  393. ;MoreEvents handles the case where several events may be linked and
  394. ; can extract one of them from the middle.
  395.  
  396. MoreEvents    ;move.l  a0,a1         ;Temporary for unlinking
  397.         move.l    d1,a0        ;Look here next...
  398.         cmpi.w    #$0200,ie_Class(a0)
  399.         bne.s    KeepLooking
  400.         move.l    ie_Code(a0),d1
  401.         andi.w    #%0011000000000000,d1
  402.         cmpi.l    #$00680000,d1
  403.         bne.s    KeepLooking
  404. ;
  405. ;Don't unlink the event, that would cause problems.
  406. ;
  407. CheckClick    movem.l a6/a1/d3/d2/d0,-(a7)
  408.         move.l    a0,-(a7)
  409. IBASE2        move.l    #-1,a6        ;Self-modifying-> Intuitionbase
  410.         move.l    TimeSave+0(pc),d0
  411.         move.l    TimeSave+4(pc),d1
  412.         move.l    ie_TimeStamp+0(a0),d2
  413.         move.l    ie_TimeStamp+4(a0),d3
  414.         jsrlib    DoubleClick
  415.         move.l    (a7)+,a0
  416.         lea.l    TimeSave+0(pc),a1
  417.         move.l    ie_TimeStamp+0(a0),(a1)+
  418.         move.l    ie_TimeStamp+4(a0),(a1)+
  419.         tst.l    d0
  420.         movem.l (a7)+,d0/d2/d3/a1/a6    ;cc's not
  421.         beq.s    KeepLooking
  422.  
  423.         ;[d0-short input]
  424.  
  425. ;The pointer to the currently active Screen and Windows are available at a
  426. ; positive offset from the Intuition base pointer.  These will be brought
  427. ; to the front.  Note that it may not be proper under the Amiga system to
  428. ; do this in the actual handler.  It may be safer to have another task
  429. ; lying around in the background to do the actual work.  The description
  430. ; of the Intuition WindowToFront commands indicates that it will not take
  431. ; effect until the NEXT input event, which (of course) will not happen
  432. ; until this one exits.  Now, if Intuition was a device...
  433. ;
  434. tofront:    movem.l a6/d0,-(a7)
  435. IBASE1        move.l    #-1,a6        ;Self-modifying-> Intuitionbase
  436.         moveq    #0,d0
  437.         jsrlib    LockIBase    ;Lock before reading any private
  438.         move.l    d0,-(a7)    ;Intuition structures
  439.  
  440.     ;move.l  ib_ActiveScreen(a6),d0      ;Uncomment to bring screen
  441.     ;beq.s     iinoscreen             ;to front also
  442.     ;move.l  d0,a0
  443.     ;jsrlib  ScreenToFront
  444.  
  445.         ;move.l  ib_ActiveScreen(a6),d0     ;Garbage, forget it
  446.         ;beq.s     inoscreen
  447.         ;move.l  d0,a0
  448.         ;lea.l     MouseYX(pc),a1
  449.         ;move.l  sc_MouseX(a0),d1
  450.         ;cmp.l     d1,(a1)
  451.         ;bne.s     imousemoved     ;The mouse moved!! Don't do it!!
  452.         ;move.l  d1,(a1)
  453.         ;jsrlib  ScreenToFront
  454.  
  455. iinoscreen    move.l    ib_ActiveWindow(a6),d0
  456.         beq.s    inowindow
  457.         move.l    d0,a0
  458.         jsrlib    WindowToFront
  459. inowindow    move.l    (a7)+,a0
  460.         jsrlib    UnlockIBase
  461.         movem.l (a7)+,d0/a6    ;d0 contains output pointer
  462.         rts
  463.  
  464. imousemoved    ;move.l  d1,(a1)     ;Set last position
  465. inoscreen    ;move.l  (a7)+,a0
  466.         ;jsrlib  UnlockIBase
  467.         ;movem.l (a7)+,d0/a6
  468.         ;rts    ;don't bother with remaining chained events
  469.  
  470. PopName:    dc.b    'ClickToFront',0
  471.         cnop    0,4    ;Pad out to Longword boundary
  472. TimeSave:    dc.l    0,0    ;longs on longs retain long
  473. ;MouseYX     dc.l     0
  474. DownEnd
  475.         END
  476.